﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Meta;
using SdmxMl.Manager;
using SdmxMl.Multiplexor;
using SdmxMl.Structure;

namespace Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Dlg
{
    public partial class DlgModuleSelect : Form
    {
        private DataSet ds;
        private ImageList imageListBook;

        #region Event

        /// <summary> Publishes the method definition in the form of a delegate </summary>
        /// <param name="sender"></param>/ <param name="e">CancelEventArgs instance</param>
        public delegate void ModuleSelectedEvent(object sender, ModuleBookEventArgs e);

        public event ModuleSelectedEvent ModuleSelected;
        public void RaiseModuleSelected(string fullId, TableOfContents moduleType)
        {
            ModuleBookEventArgs evArg = new ModuleBookEventArgs(fullId, moduleType);
            ModuleSelectedEvent eventHandler = this.ModuleSelected;

            if (eventHandler != null)
                eventHandler(this, evArg);
        }
        #endregion


        public string ModuleFullId { get; private set; }

        public DlgModuleSelect(TableOfContents moduleType, string AgencyId, ImageList imgList)
        {
            InitializeComponent();
            imageListBook = imgList;

            //Make combo box draw mode to variable draw mode 
            //this will allow us to draw combo box in our style
            comboBoxArtefactType.DrawMode = DrawMode.OwnerDrawVariable;
            //using DrawItem event we need to draw item
            comboBoxArtefactType.DrawItem += new DrawItemEventHandler(comboBox1_DraItemEvent);

            // Fill all module type availables
            BookHierarchy BookPossibleContent = new BookHierarchy("", true);

            // Add menu sub items
            foreach (TableOfContents toc in Enum.GetValues(typeof(TableOfContents)))
            {
                comboBoxArtefactType.Items.Add(new ComboArtefactTypeItem(toc));
                if (toc == moduleType)
                    comboBoxArtefactType.SelectedItem = comboBoxArtefactType.Items[comboBoxArtefactType.Items.Count-1];
            }

            comboBoxArtefactType.SelectedIndexChanged += new EventHandler(comboBoxAgency_SelectedIndexChanged);
            comboBoxAgency.SelectedIndexChanged += new EventHandler(comboBoxAgency_SelectedIndexChanged);
            comboBoxAgency.TextUpdate += new EventHandler(comboBoxAgency_TextUpdate);
            comboBoxArtefactId.SelectedIndexChanged += new EventHandler(comboBoxArtefactId_SelectedIndexChanged);
            comboBoxArtefactId.TextUpdate += new EventHandler(comboBoxArtefactId_TextUpdate);

            // Fill combo agencies with NSI agencies
            OrganisationSchemesType orgNsi = SdmxMl.Msg.HeaderGenerator.NSI_OrgScheme;
            if (orgNsi != null)
            {
                foreach (OrganisationType o in orgNsi.Agencies)
                    comboBoxAgency.Items.Add(o.Id);
            }
            //Select user group
            if (comboBoxAgency.Items.Contains(AgencyId))
                comboBoxAgency.SelectedItem = AgencyId;
            else
                comboBoxAgency.SelectedIndex = -1;
        }

        private void comboBox1_DraItemEvent(object sender, DrawItemEventArgs e)
        {
            //draw back groud of the item
            e.DrawBackground();
            //Create a Image from a file
            Image img = imageListBook.Images[e.Index];
            //Draw the image in combo box using its bound, here size of image is
            // 10, 10 you can increase the size if you want
            e.Graphics.DrawImage(img, e.Bounds.X, e.Bounds.Y, 15, 15);
            //we need to draw the item as string because we made drawmode to ownervariable
            e.Graphics.DrawString(comboBoxArtefactType.Items[e.Index].ToString(), comboBoxArtefactType.Font,
                System.Drawing.Brushes.Black,
                new RectangleF(e.Bounds.X + 15, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
            //draw rectangle over the item selected
            e.DrawFocusRectangle();
        }

        private void comboBoxAgency_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateComboArtefactId();
        }

        private void comboBoxAgency_TextUpdate(object sender, EventArgs e)
        {
            UpdateComboArtefactId();
        }

        private void comboBoxArtefactId_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateComboVersion();
        }

        private void comboBoxArtefactId_TextUpdate(object sender, EventArgs e)
        {
            UpdateComboVersion();
        }

        /// <summary>
        /// If Internal NSI Agency Group selected, update combo with artefacts of group selected
        /// </summary>
        private void UpdateComboArtefactId()
        {
            ds = null;

            // Default
            List<string> aList = new List<string>();

            comboBoxArtefactId.Items.Clear();
            comboBoxArtefactId.Text = string.Empty;

            //Do we need to fill
            if (comboBoxArtefactType.SelectedIndex >= 0 && comboBoxAgency.Text.Length > 0)
            {
                using (new SdmxMl.Helper.CWaitCursor())
                {
                    ds = Mux.Instance.DirInfo((comboBoxArtefactType.SelectedItem as ComboArtefactTypeItem).ArType.ToString(), comboBoxAgency.Text+ "+1+1");
                    if (ds != null && ds.Tables.Count > 0)
                    {
                        DataTable tb = ds.Tables[0];
                        foreach (DataRow row in tb.Rows)
                        {
                            if (row["AI"].ToString() == comboBoxAgency.Text)
                                if (aList.Contains(row["ID"].ToString()) == false)
                                    aList.Add(row["ID"].ToString());
                        }
                        comboBoxArtefactId.Items.Clear();
                        aList.Sort();

                        comboBoxArtefactId.Items.AddRange(aList.ToArray());
                        if (comboBoxArtefactId.Items.Count > 0)
                            comboBoxArtefactId.SelectedIndex = 0;


                    }
                }
            }

            UpdateComboVersion();
        }


        /// <summary>
        /// If Internal NSI Agency Group and Artefact ID selected, update combo with versions of artefact selected
        /// </summary>
        private void UpdateComboVersion()
        {
            List<string> aList = new List<string>();

            comboBoxVersion.Items.Clear();

            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable tb = ds.Tables[0];
                foreach (DataRow row in tb.Rows)
                {
                    if (row["AI"].ToString() == comboBoxAgency.Text && row["ID"].ToString() == comboBoxArtefactId.Text)
                        if (aList.Contains(row["VER"].ToString()) == false)
                            aList.Add(row["VER"].ToString());
                }
                comboBoxVersion.Items.Clear();
                comboBoxVersion.Text = string.Empty;
                aList.Sort();

                comboBoxVersion.Items.AddRange(aList.ToArray());
                if (comboBoxVersion.Items.Count > 0)
                    comboBoxVersion.SelectedIndex = 0;
            }
        }

        private void buttonSubmit_Click(object sender, EventArgs e)
        {
            // Check fully filled
            if (comboBoxAgency.Text.Length == 0 || comboBoxArtefactId.Text.Length == 0 ||
                comboBoxVersion.Text.Length == 0)
            {
                MessageBox.Show(this, "Some fields are empty !", "Module", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                ModuleFullId = comboBoxAgency.Text + "+" + comboBoxArtefactId.Text + "+" + comboBoxVersion.Text;
                ComboArtefactTypeItem item = comboBoxArtefactType.SelectedItem as ComboArtefactTypeItem;
                RaiseModuleSelected(ModuleFullId, item.ModuType);
            }
        }

    }

    /// <summary>
    /// Class to correct some display in combo of artefact types
    /// </summary>
    internal class ComboArtefactTypeItem
    {
        internal SdmxArtefactType ArType { get; private set; }
        public TableOfContents ModuType { get; private set; }

        internal ComboArtefactTypeItem(TableOfContents moduleType)
        {
            ModuType = moduleType;
            switch (moduleType)
            {
                case TableOfContents.Overview:
                case TableOfContents.Book:
                case TableOfContents.Questionnaires:
                    ArType = SdmxArtefactType.MetadataSet;
                    break;
                case TableOfContents.Catalog:
                    ArType = SdmxArtefactType.Concepts;
                    break;
                case TableOfContents.DataTables:
                    ArType = SdmxArtefactType.KeyFamilies;
                    break;
                case TableOfContents.Codelists:
                    ArType = SdmxArtefactType.CodeLists;
                    break;
                case TableOfContents.Correspondences:
                    ArType = SdmxArtefactType.StructureSets;
                    break;
                case TableOfContents.Hierarchies:
                    ArType = SdmxArtefactType.HierarchicalCodelists;
                    break;
                default:
                    ArType = SdmxArtefactType.None;
                    break;
            }

        }

        public override string ToString()
        {
            return ModuType.ToString();
        }

    }

}
